home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagn_r.zip / NUMBERS.SWG / 0062_Huge Numbers!.pas < prev    next >
Pascal/Delphi Source File  |  1995-03-03  |  4KB  |  226 lines

  1. unit HugeUtil;
  2.  
  3. interface
  4.  
  5. const HugeMax = $8000-16;
  6.  
  7. type  Huge = record
  8.               len : word;
  9.               dat : array[1..HugeMax] of word;
  10.             end;
  11.       HugePtr = ^Huge;
  12.  
  13. procedure AddHuge  (var Answer, Add : Huge);
  14. procedure MulHuge  (var A : Huge; Mul : integer; var Answer : Huge);
  15. procedure DivHuge  (var A : Huge; Del : integer; var Answer : Huge;
  16.                     var Remainder : integer);
  17. procedure SubHuge  (var Answer, Sub : Huge);
  18. procedure ZeroHuge (var L : Huge; Size : word);
  19. procedure CopyHuge (var Fra,Til : Huge);
  20. procedure GetHuge  (var P : HugePtr; Size : word);
  21. procedure WriteHuge(var L : Huge; Size: word);
  22.  
  23. implementation
  24.  
  25. procedure AddHuge; assembler; asm
  26.   cld
  27.   push  ds
  28.   lds   di,Answer
  29.   les   si,Add
  30.   seges lodsw
  31.   mov   cx,ax
  32.   clc
  33. @l1:
  34.   seges lodsw
  35.   adc   [si-2],ax
  36.   loop  @l1
  37.   jnb   @done
  38. @l2:
  39.   add   word [si],1
  40.   inc   si
  41.   inc   si
  42.   jc    @l2
  43. @done:
  44.   mov   si,di
  45.   lodsw
  46.   shl   ax,1
  47.   add   si,ax
  48.   lodsw
  49.   or    ax,ax
  50.   je    @d2
  51.   inc   word [di]
  52. @d2:
  53.   pop   ds
  54. end;
  55.  
  56. procedure MulHuge; assembler; asm
  57.   cld
  58.   push  ds
  59.   lds   si,A
  60.   mov   bx,Mul
  61.   les   di,Answer
  62.   mov   cx,[si]
  63.   mov   dx,si
  64.   inc   di
  65.   inc   di
  66.   clc
  67. @l1:
  68.   mov   ax,[di]
  69.   pushf
  70.   mul   bx
  71.   popf
  72.   adc   ax,si
  73.   stosw
  74.   mov   si,dx
  75.   loop  @l1
  76.   adc   si,0
  77.   mov   es:[di],si
  78.   lds   di,A
  79.   mov   di,[di]
  80.   mov   ax,[di+2]
  81.   or    ax,ax
  82.   je    @l2
  83.   inc   di
  84.   inc   di
  85. @l2:
  86.   lds   si,Answer
  87.   mov   [si],di
  88.   pop   ds
  89. end;
  90.  
  91. procedure DivHuge; assembler; asm
  92.   std
  93.   push  ds
  94.   lds   si,A
  95.   mov   bx,Del
  96.   les   di,Answer
  97.   mov   cx,[si]
  98.   mov   di,cx
  99.   add   di,cx
  100.   xor   dx,dx
  101. @l1:
  102.   mov   ax,[di]
  103.   div   bx
  104.   stosw
  105.   loop  @l1
  106.   lds   si,Remainder
  107.   mov   [si],dx
  108.   lds   si,A
  109.   mov   ax,[si]
  110.   lds   di,Answer
  111.   mov   [di],ax
  112.   mov   si,[di]
  113.   shl   si,1
  114. @d3:
  115.   lodsw
  116.   or    ax,ax
  117.   jne   @d2
  118.   dec   word [di]
  119.   jne   @d3
  120.   inc   word [di]
  121. @d2:
  122.   pop   ds
  123. end;
  124.  
  125. procedure SubHuge; assembler; asm
  126.   cld
  127.   push  ds
  128.   lds   di,Answer
  129.   les   si,Sub
  130.   seges lodsw
  131.   mov   cx,ax
  132.   clc
  133. @l1:
  134.   seges lodsw
  135.   sbb   [si-2],ax
  136.   loop  @l1
  137.   jnb   @done
  138. @l2:
  139.   sub   word [si],1
  140.   inc   si
  141.   inc   si
  142.   jc    @l2
  143. @done:
  144.   mov   si,[di]
  145.   shl   si,1
  146.   std
  147. @d3:
  148.   lodsw
  149.   or    ax,ax
  150.   jne   @d2
  151.   dec   word [di]
  152.   jne   @d3
  153.   inc   word [di]
  154. @d2:
  155.   pop   ds
  156. end;
  157.  
  158.  
  159. procedure WriteHuge;
  160. var L1, L2, I, R, R1, X : integer;
  161. begin
  162.   with L do begin
  163.     L1 := Len;
  164.     L2 := L1 - 1;
  165.     I := 1;
  166.     write(dat[L1],'.');
  167.     X := 0;
  168.     for I := 1 to Size div 4 do begin
  169.       Dat[L1] := 0;
  170.       Len := L2;
  171.       MulHuge(L,10000,L);
  172.       R := dat[L1];
  173.       R1 := R div 100;
  174.       R  := R mod 100;
  175.       write(chr(R1 div 10+48), chr(R1 mod 10+48),
  176.             chr(R  div 10+48), chr(R  mod 10+48));
  177.       inc(X);
  178.       write(' ');
  179.       if X > 14 then begin
  180.         writeln; write('  ');
  181.         X := 0
  182.       end
  183.     end
  184.   end;
  185.   writeln
  186. end;                            { WriteHuge }
  187.  
  188. procedure ZeroHuge;
  189. begin
  190.   fillchar(L.Dat, Size * 2, #0);
  191.   L.Len := Size
  192. end;
  193.  
  194. procedure CopyHuge;
  195. begin
  196.   move(Fra, Til, Fra.Len * 2 + 2)
  197. end;
  198.  
  199. procedure GetHuge;
  200. var D : ^byte;
  201.     Tries,
  202.     Bytes : word;
  203. begin
  204.   Bytes := 2 * (Size + 1);
  205.   Tries:=0;
  206.   repeat
  207.     getmem(P,Bytes);
  208.  
  209. { To make it possible to use maximally large arrays, and to increase
  210.   the speed of the computations, all records of type Huge MUST start
  211.   at a segment boundary! }
  212.  
  213.     if ofs(P^) = 0 then begin
  214.       ZeroHuge(P^,Size);
  215.       exit
  216.     end;
  217.     inc(Tries);
  218.     freemem(P,Bytes);
  219.     new(D)
  220.   until Tries>10;   { if not done yet, it's not likely we ever will be }
  221.   writeln('Couldn''t get memory for array');
  222.   halt(1)
  223. end;                                   { GetHuge }
  224.  
  225. end.
  226.